using System;

namespace Lichtspiel.Utility
{
    /// <summary>
    /// A managed collection of timers.
    /// </summary>
    public sealed class TimerCollection : IUpdateable
    {
        private const int InitialPoolSize = 10;
        private readonly Pool<Timer> timers = new Pool<Timer>(InitialPoolSize, t => t.IsActive);

        #region IUpdateable Members

        /// <summary>
        /// Updates all timers in the collection.
        /// </summary>
        public void Update(GameTime time) {
            lock (timers) {
                for (int i = 0; i < timers.ValidCount; i++) {
                    timers[i].Update(time);
                }
                timers.CleanUp();
            }
        }

        #endregion

        /// <summary>
        /// Creates a new Timer.
        /// </summary>
        /// <param name="tickLength">The amount of time between the timer's ticks.</param>
        /// <param name="repeats">Whether or not the timer repeats.</param>
        /// <param name="tick">An action to perform when the timer ticks.</param>
        /// <returns>The new Timer object or null if the timer pool is full.</returns>
        public Timer Create(TimeSpan tickLength, bool repeats, Action<Timer> tick) {
            if (tickLength <= TimeSpan.Zero) {
                throw new ArgumentException("tickLength must be greater than zero.");
            }
            if (tick == null) {
                throw new ArgumentNullException("tick");
            }

            lock (timers) {
                // get a new timer from the pool
                Timer t = timers.New();
                t.Reset(tickLength, repeats, tick);

                return t;
            }
        }

        public void StopAll() {
            lock (timers) {
                for (int i = 0; i < timers.ValidCount; i++) {
                    timers[i].Stop();
                }
                timers.CleanUp();
            }
        }
    }
}